﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Graphics;
using System.Threading;
using Microsoft.Xna.Framework.GamerServices;
using System.IO;
using System.Reflection;

namespace LGE
{
    public static class GameScreenManager
    {
        static Stack<GameScreen> GameScreens = new Stack<GameScreen>();

        public static Texture2D blackScreen;
        static GameScreen transScreen = null;
        static bool isTransitioningIn = false;
        static bool isTransitioningOut = false;
        static int transDuration = 250;
        static double transTimer = 0;
        static GameScreen startScreen = null;

        /// <summary>
        /// Função que inicializa o GameScreenManager. Deve ser chamada no LoadContent da Game.
        /// </summary>
        /// <param name="game">Game que a manager tratará.</param>
        /// <param name="startScreen">Primeira tela do jogo.</param>
        public static void Start(GameScreen startScreen)
        {
            // cria o BlackScreen
            blackScreen = new Texture2D(Engine.game.GraphicsDevice, Engine.viewport.Width, Engine.viewport.Height);
            //Texture2D.FromStream(game.GraphicsDevice, Assembly.GetExecutingAssembly().GetManifestResourceStream("LGE.Resources.BlackScreen.png"));
            Color[] v = new Color[blackScreen.Height * blackScreen.Width];
            for (int i = 0; i < blackScreen.Height * blackScreen.Width; i++) v[i] = Color.Black;
            blackScreen.SetData<Color>(v);

            GameScreenManager.startScreen = startScreen;
            Push(startScreen);
        }

        public static void Update(GameTime gameTime)
        {
            if (Audio.audioEngine != null) Audio.Update(gameTime);
            if (isTransitioningIn) return;
            Input.Update(gameTime);
            if (GameScreens.Count > 0) GameScreens.Peek().Update(gameTime);
        }

        public static void Draw(GameTime gameTime, SpriteBatch spriteBatch)
        {
            spriteBatch.GraphicsDevice.Clear(Color.DarkGray);
            if (isTransitioningIn) DrawTransitionIn(gameTime, spriteBatch);
            else
            {
                if (GameScreens.Count > 0) GameScreens.Peek().Draw(gameTime, spriteBatch);
                if (isTransitioningOut) DrawTransitionOut(gameTime, spriteBatch);
            }
        }

        public static void DrawTransitionIn(GameTime gameTime, SpriteBatch spriteBatch)
        {
            transTimer += gameTime.ElapsedGameTime.TotalMilliseconds;
            if (transTimer > transDuration)
            {
                transTimer = transDuration;
                isTransitioningIn = false;
                isTransitioningOut = true;
                transScreen = null;
            }
            float a = (float)(transTimer / (transDuration / 2));
            if (a > 1) a = 1;
            if (transScreen != null) transScreen.Draw(gameTime, spriteBatch);
            spriteBatch.Draw(blackScreen, Vector2.Zero, new Color(0f, 0f, 0f, a));
        }
         
        public static void DrawTransitionOut(GameTime gameTime, SpriteBatch spriteBatch)
        {
            transTimer -= gameTime.ElapsedGameTime.TotalMilliseconds;
            if (transTimer < 0)
            {
                transTimer = 0;
                isTransitioningIn = false;
                isTransitioningOut = false;
                return;
            }
            float a = (float)(transTimer / (transDuration / 2));
            if (a > 1) a = 1; if (a < 0) a = 0;
            spriteBatch.Draw(blackScreen, Vector2.Zero, new Color(0f, 0f, 0f, a));
        }

        public static void Push(GameScreen gameScreen)
        {
            Push(gameScreen, true);
        }

        public static void Push(GameScreen gameScreen, bool transition)
        {
            if (transition)
            {
                isTransitioningIn = true;
                if (GameScreens.Count > 0) transScreen = GameScreens.Peek();
            }
            GameScreens.Push(gameScreen);
            if (transition) 
                Push(new LoadScreen(gameScreen), false);
        }

        public static void Pop()
        {
            Pop(true);
        }

        public static void Pop(bool transition)
        {
            isTransitioningIn = transition;
            if (transition)
                transScreen = GameScreens.Pop();
            else
            {
                transScreen = null;
                GameScreens.Pop();
            }
        }

        public static void ChangeScreen(GameScreen gs)
        {
            ChangeScreen(gs, true);
        }
        
        public static void ChangeScreen(GameScreen gs, bool transition)
        {
            Pop(transition);
            Push(gs, transition);
        }

        public static void Reset()
        {
            GameScreens.Clear();
            GameScreenManager.Push(startScreen);
        }

        public static void SetLoadScreenBG(Texture2D sprite)
        {
            LoadScreen.background = sprite;
        }
    }
}
